package in.muton.edushare.academics.panels;

import in.muton.edushare.EduShareSession;
import in.muton.edushare.processing.objects.CourseDataHandler;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.wicket.model.Model;

import com.edushare.common.dao.DepartmentsDAO;
import com.edushare.common.dao.GradeKeyDAO;
import com.edushare.common.dao.academics.grades.EntityLetterGrade;
import com.edushare.common.dao.academics.grades.LetterGradeMap;
import com.edushare.common.dao.academics.grades.UnivLetterGrades;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.vo.CourseInstances;
import com.edushare.common.vo.Departments;
import com.edushare.common.vo.GradeKey;
import com.edushare.common.vo.Universities;

public class GradePanelUtil {

	public static void copyToTuple(GradeKey k, GradeKeyHelper t){
		t.gpaValue = k.getGradeNumber();
		t.gradeName = k.getGradeAlphabet();
		t.maxMarks = k.getMaximumMarks();
		t.minMarks = k.getMinimumMarks();
		t.passGrade = k.isPass();		
	}
	
	public static List<GradeKeyHelper> getTuples(Universities univ) {
		UnivLetterGrades ulg = new UnivLetterGrades(getORM());
		List<GradeKey> gkList = ulg.getSetOfGrades(univ, ulg
				.getLatestVersion(univ));
		List<GradeKeyHelper> tupleList = new ArrayList<GradeKeyHelper>();
		for (GradeKey k : gkList) {
			GradeKeyHelper t = new GradeKeyHelper();
			copyToTuple(k, t);
			tupleList.add(t);
		}
		if (tupleList.size() == 0) {
			GradeKeyHelper t = new GradeKeyHelper();
			tupleList.add(t);
		}
		return tupleList;
	}

	public static List<GradeKeyHelper> getTuples(Departments dept) {
		Universities univ = new DepartmentsDAO(getORM()).getParent(dept);
		EntityLetterGrade elg = new EntityLetterGrade(getORM());
		UnivLetterGrades ulg = new UnivLetterGrades(getORM());
		if (ulg.hasLetterGrades(univ) && !elg.deptHasGrades(dept)) {
			elg.copyDeptGrade(dept);
		}
		List<GradeKey> gkList = elg.getDeptGrades(dept);
		List<GradeKeyHelper> tupleList = new ArrayList<GradeKeyHelper>();
		for (GradeKey k : gkList) {
			GradeKeyHelper t = new GradeKeyHelper();
			copyToTuple(k, t);
			tupleList.add(t);
		}
		return tupleList;
	}

	public static List<GradeKeyHelper> getTuples(CourseInstances course) {
		Universities univ = new CourseDataHandler(new Model<CourseInstances>(
				course)).getOwnerUniv().getObject();
		EntityLetterGrade elg = new EntityLetterGrade(getORM());
		UnivLetterGrades ulg = new UnivLetterGrades(getORM());
		if (ulg.hasLetterGrades(univ) && !elg.courseHasGrade(course)) {
			elg.copyCourseGrade(course);
		}
		List<GradeKey> gkList = elg.getCourseGrades(course);
		List<GradeKeyHelper> tupleList = new ArrayList<GradeKeyHelper>();
		for (GradeKey k : gkList) {
			GradeKeyHelper t = new GradeKeyHelper();
			copyToTuple(k, t);
			tupleList.add(t);
		}
		return tupleList;
	}

	public static class GradeKeyHelper implements Comparable<GradeKeyHelper>, Serializable {
		private static final long serialVersionUID = -1240906258380272065L;

		public double maxMarks = 100.0;
		public double minMarks = 0.0;
		public double gpaValue = 10.0;
		public String gradeName = "";
		public int gradeKey = 0;
		public boolean passGrade = true;

		public int compareTo(GradeKeyHelper arg0) {
			if (minMarks < arg0.minMarks)
				return -1;
			if (minMarks > arg0.minMarks)
				return 1;
			return 0;
		}
	}
	
	public static void removeTuple(GradeKeyHelper t, Universities univ){
		LetterGradeMap lgm = new LetterGradeMap(getORM());
		GradeKey k = lgm.getGradeKey(t.gradeName, univ);
		new UnivLetterGrades(getORM()).removeGrade(k);
	}

	public static String saveTuples(List<GradeKeyHelper> tupleList) {
		GradeKeyDAO gkDAO = new GradeKeyDAO(getORM());
		EntityLetterGrade elg = new EntityLetterGrade(getORM());
		Collections.sort(tupleList);
		Collections.reverse(tupleList);
		for (int i = 0; i < tupleList.size() - 1; i++) {
			if (tupleList.get(i).maxMarks == tupleList.get(i + 1).minMarks) {
				return "The maximum marks for one grade should be equal to "
						+ "minimum marks for next grade";
			}
		}

		for (GradeKeyHelper t : tupleList) {
			elg.editGrade(gkDAO.getKeyByPk(t.gradeKey), t.maxMarks, t.minMarks);
		}
		return "Saved grades.";
	}

	private static ORMInterface getORM() {
		return EduShareSession.get().getSessionORMInterface();
	}
}
